<template>
  <div class="process">
    <el-container>
      <el-aside v-show="editFlow"
                class="left">
        <div v-for="item in menuList"
             :key="item.id"
             :id="item.nodeType"
             :name="item.nodeName"
             :draggable="canModify"
             class="item-dom avue-draggable__item"
             @dragstart="drag($event)"
             :title="item.nodeName"
             v-show="item.isShow !== false">
          <div :class="['node',(item.nodeName === $t('processDialog.nodeName.start')||item.nodeName === $t('processDialog.nodeName.end'))?'radio-node':'']"
               :style="{backgroundImage: 'url(' + item.icon + ')'}"></div>
        </div>
      </el-aside>
      <el-main>
        <div @dragover="allowDrop($event)"
             @drop="drop($event)"
             class="right-content">
          <flow :boxId="boxId"
                :option="option"
                :nodeMaintain="nodeMaintain"
                :simple="!editFlow"
                :isDrag="editFlow"
                :lastNode="lastNode"
                :limitNode="limitNode"
                :orgId="orgId"
                @clickNode="handleClick"
                @updateMenuList="updateMenuList"
                @delNode="delNode"
                @addNode="addNode"
                @changeNodeSite="changeNodeSite"
                ref="flow"></flow>
        </div>
      </el-main>
    </el-container>
    <drawer :visible="drawerVisible"
            @close="drawerVisible = false">
      <div class="drawer">
        <node-info :currentNode="currentNode"
                   :nodeList="deepClone(nodeList)"
                   :lineList="deepClone(lineList)"
                   :orgId="orgId"
                   :status="status"
                   :tempId="tempId"
                   :approvalData="approvalData"
                   :busiOption="busiOption"
                   :nodeMaintain="nodeMaintain"
                   @confirmNode="confirmNode"
                   @close="drawerVisible = false"
                   ref="nodeInfo"></node-info>
      </div>
    </drawer>
  </div>
</template>

<script>
import drawer from '../Drawer'
import flow from './flow'
import { deepClone } from '../../util/util'
import nodeInfo from './nodeInfo'
import flowBack from '../../assets/img/flowBack.png';
import flowEmail from '../../assets/img/flowEmail.png';
import flowMeet from '../../assets/img/flowMeet.png';
import flowSign from '../../assets/img/flowSign.png';
import flowStart from '../../assets/img/flowStart.png';
import flowStop from '../../assets/img/flowStop.png';
import flowUser from '../../assets/img/flowUser.png';

export default {
  components: { drawer, flow, nodeInfo },
  props: {
    nodeList: {
      type: Array,
      default: []
    },
    lineList: {
      type: Array,
      default: []
    },
    tempId: {
      type: Number
    },
    orgId: {
      type: Number
    },
    status: {
      type: Array,
      default: []
    },
    approvalData: {
      type: Array,
      default: []
    },
    busiOption: {
      type: Array,
      default: []
    },
    nodeMaintain: { // 是否审批节点维护
      type: Boolean,
      default: false
    },
    editFlow: {
      type: Boolean,
      default: true
    },
    lastNode: {
      type: Object,
      default: () => {
        return {}
      }
    },
    limitNode: {
      type: Array,
      default: () => {
        return []
      }
    },
    boxId: String,
  },
  watch: {
    option: {
      handler () {
        console.log(this.option)
        if (new Set(this.option.lineList.map(res => {
          return `${res.fromId}` + `${res.toId}`
        })).size !== this.option.lineList.length) this.$message.warning(this.$t('processDialog.cannotMultiFlows'))
        this.$emit('changeLineList', this.option.lineList)
      },
      deep: true
    },
    nodeList: {
      handler: 'changeNode',
      deep: true
    },
    drawerVisible () {
      if (this.drawerVisible) {
        this.$refs.nodeInfo.type = '1'
        this.$refs.nodeInfo.getDecisionData()
        this.$refs.nodeInfo.nodeOption = []
        this.$refs.nodeInfo.getBackNode(this.currentNode.id)
      }
    },
    tempId () {
      this.menuList.some(res => {
        res.tempId = this.tempId
      })
    }
  },
  data () {
    return {
      option: {
        lineList: this.lineList,
        nodeList: deepClone(this.nodeList)
      },
      drawerVisible: false,
      currentX: undefined,
      currentY: undefined,
      domX: undefined,
      domY: undefined,
      menuList: [{
        nodeName: this.$t('processDialog.nodeName.start'),
        isShow: true,
        nodeType: 1,
        isAddable: 1, // 可新增后续节点
        isDeletable: 1, // 可删除
        isEditable: 0, // 可编辑
        tempId: this.tempId,
        icon: flowStart,
        orgId: this.orgId
      }, {
        nodeName: this.$t('processDialog.nodeName.end'),
        nodeType: 2,
        isAddable: 0, // 可新增后续节点
        isDeletable: 1, // 可删除
        isEditable: 0, // 可编辑
        tempId: this.tempId,
        icon: flowStop,
        orgId: this.orgId
      }, {
        nodeName: this.$t('processDialog.nodeName.userTask'),
        icon: flowUser,
        nodeType: 3,
        assignee: '',
        assigneeType: 1,
        backTo: '',
        expireIn: '',
        expireTime: '',
        expireUnit: 'hour',
        isTransferable: 0, // 超时未处理是否移交候选人
        isAddable: 1, // 可新增后续节点
        isDeletable: 1, // 可删除
        isEditable: 1, // 可编辑
        tempId: this.tempId, // 模板id
        orgId: this.orgId
      }, {
        nodeName: this.$t('processDialog.nodeName.assigneeTask'),
        icon: flowMeet,
        nodeType: 4,
        approvalsCnt: 0,
        assignee: '',
        assigneeType: 1,
        expireIn: '',
        expireTime: '',
        expireUnit: 'hour',
        isTransferable: 0, // 超时未处理是否移交候选人
        isAddable: 1,
        isDeletable: 1,
        isEditable: 1,
        tempId: this.tempId,
        ctsNodes: [
          {
            assignee: '',
            assigneeType: 1
          }
          //   { // 流程模板会签任务节点新增对象
          // 	"assignee": "",
          // 	"assigneeType": 0,
          // 	"id": 0,
          // 	"isMandatory": 0,
          // 	"nodeId": 0,
          // 	"tempId": 0
          // }
        ],
        ctsConditions: [
          {
            approvalsCnt: 0,
            ctsNodeId: '',
            id: `${new Date().getTime()}`
          }
        ],
        orgId: this.orgId
      },
      // {
      //   nodeName: '邮件任务',
      //   nodeType: 5,
      //   icon:flowEmail
      // },
      {
        nodeName: this.$t('processDialog.nodeName.backTask'),
        icon: flowBack,
        nodeType: 6,
        isAddable: 1,
        isDeletable: 1,
        isEditable: 1,
        tempId: this.tempId,
        orgId: this.orgId
      }, {
        nodeName: this.$t('processDialog.nodeName.notificationTask'),
        icon: flowSign,
        nodeType: 7,
        assignee: '',
        assigneeType: 1,
        isAddable: 1,
        isDeletable: 1,
        isEditable: 1,
        tempId: this.tempId,
        orgId: this.orgId
      }],
      canModify: true,
      currentNode: {},
      loadNodeData: false
    }
  },
  methods: {
    changeNode () {
      if (this.loadNodeData) return
      this.nodeList.some(res => {
        if (res.nodeName === this.$t('processDialog.nodeName.start')) {
          this.menuList[0].isShow = false
          return true
        }
      })
      this.nodeList.some(res => { res.lineDisabled = this.nodeMaintain })
      this.option.nodeList = deepClone(this.nodeList)
      this.option.lineList = deepClone(this.lineList)
      this.$refs.flow.loadView(this.nodeList, this.lineList)
      this.loadNodeData = true
    },
    drag (ev) {
      this.currentX = undefined
      this.currentY = undefined
      this.domX = ev.offsetX
      this.domY = ev.offsetY
      ev.dataTransfer.setData("Text", ev.target.id)
    },
    drop (ev) {
      if (!this.canModify) return
      const id = ev.dataTransfer.getData("Text")
      if (this.menuList[0].isShow && `${this.menuList[0].nodeType}` === id) this.menuList[0].isShow = false
      let data = {}
      this.menuList.some(res => {
        if (`${res.nodeType}` === id) {
          data = res
          return true
        }
      })
      if (!data.nodeType) return
      const obj = {
        ...data,
        leftCoord: (this.currentX - this.domX) || 0,
        topCoord: (this.currentY - this.domY) || 0
      }
      this.$refs.flow.addNode(obj)
      ev.preventDefault();
    },
    // 新增节点
    addNode (node) {
      this.nodeList.push(node)
    },
    // 删除节点
    delNode (id) {
      this.nodeList.some((res, index) => {
        if (res.id === id) {
          this.nodeList.splice(index, 1)
          return true
        }
      })
    },
    // 更改节点位置
    changeNodeSite ({ index, left, top }) {
      this.nodeList.some((res, i) => {
        if (i === index) {
          this.$set(res, 'leftCoord', left)
          this.$set(res, 'topCoord', top)
          return true
        }
      })
    },
    allowDrop (ev) {
      this.currentX = ev.offsetX
      this.currentY = ev.offsetY
      ev.preventDefault();
    },
    handleClick (node) {
      if (!this.editFlow) return
      let cFlag = false
      if (this.limitNode.length > 0)
        this.limitNode.some(res => {
          if (res.id === node.id) {
            cFlag = true
            return true
          }
        })
      if (cFlag) return
      if (node.nodeName === this.$t('processDialog.nodeName.start') || node.nodeName === this.$t('processDialog.nodeName.end')) return
      this.currentNode = deepClone(node)
      this.currentNode.isAddable = this.currentNode.isAddable === 1
      this.currentNode.isEditable = this.currentNode.isEditable === 1
      this.currentNode.isDeletable = this.currentNode.isDeletable === 1
      // 转换代理值
      if (node.nodeType === 3 || node.nodeType === 7) {
        if (this.currentNode.assignee !== '') this.currentNode.assignee = this.currentNode.assignee.split(',').map(res => { return ~~res })
        this.$refs.nodeInfo.getOption(this.currentNode.assigneeType || 1).then(res => { this.$refs.nodeInfo.ao = res })
      }
      // 转换会签任务代理值
      if (node.nodeType === 4) {
        if (this.currentNode.ctsNodes.length > 0)
          this.currentNode.ctsNodes.some(res => {
            if (res.assignee !== '' && res.assignee !== null && !Array.isArray(res.assignee))
              res.assignee = res.assignee.split(',').map(res => { return ~~res })
            if (this.nodeMaintain && res.assignedTo !== undefined && res.assignedTo !== null) res.assignedTo = res.assignedTo.split(',').map(res => { return ~~res === 0 ? null : ~~res })
            if (this.nodeMaintain && res.candidate !== undefined && res.candidate !== null) res.candidate = res.candidate.split(',').map(res => { return ~~res === 0 ? null : ~~res })
          })
        this.$refs.nodeInfo.getParallelData()
      }
      if (node.nodeType === 3 || node.nodeType === 4) this.currentNode.isTransferable = this.currentNode.isTransferable === 1
      if (this.nodeMaintain && this.currentNode.assignedTo !== undefined && this.currentNode.assignedTo !== null) this.currentNode.assignedTo = this.currentNode.assignedTo.split(',').map(res => { return ~~res === 0 ? null : ~~res })
      if (this.nodeMaintain && this.currentNode.candidate !== undefined && this.currentNode.candidate !== null) this.currentNode.candidate = this.currentNode.candidate.split(',').map(res => { return ~~res === 0 ? null : ~~res })

      this.drawerVisible = true
    },
    updateMenuList (type) {
      if (type) this.menuList[0].isShow = true
    },
    // 详情弹框确认修改值
    confirmNode (decision) {
      if (decision.length > 0) this.$refs.flow.updateLine(decision)
      for (let i = 0; i < this.nodeList.length; i++) {
        if (this.currentNode.id === this.nodeList[i].id) {
          for (const k in this.nodeList[i]) {
            this.$set(this.nodeList[i], k, this.currentNode[k])
          }
          if (this.nodeMaintain && this.currentNode.nodeType !== 4 && this.currentNode.nodeType !== 6) {
            this.nodeList[i].assignedTo = this.currentNode.assignedTo.join(',')
            this.nodeList[i].candidate = this.currentNode.candidate.join(',')
          }
          this.$refs.flow.updateNode(this.currentNode)
          break
        }
      }
      this.drawerVisible = false
    }
  }
}
</script>

<style lang="scss" scoped>
/deep/.avue-flow__node-header {
  display: flex;
  flex-flow: row nowrap;
  align-items: center;
}
.left {
  border-right: 1px solid #f1f5f8;
  display: flex;
  flex-flow: column nowrap;
  align-items: center;
  width: 72px !important;
  padding-top: 20px;
}
.myDelete {
  margin-right: 5px;
}
.item-dom {
  cursor: pointer;
  margin-bottom: 20px;
  width: 32px;
  height: 32px;
}
.node {
  width: 100%;
  height: 100%;
  display: flex;
  flex-flow: row nowrap;
  align-items: center;
  justify-content: center;
  border-radius: 5px;
  border: 1px solid #f1f5f8;
  background-repeat: no-repeat;
  background-position: center;
  img {
    width: 16px;
    height: 16px;
  }
}
.radio-node {
  border-radius: 100%;
  img {
    width: 12px;
    height: 12px;
  }
}
/deep/.myLabel {
  margin-left: 20px;
  margin-top: 20px;
}
.drawer {
  height: 100%;
}
.right-content {
  background: #f1f5f8;
  overflow: hidden;
}
</style>